package ali_api

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"github.com/smartwalle/alipay/v3"
	"log"
	"muziai-server/core"
	"muziai-server/global"
	"time"

	"muziai-server/utils/res"
)

var (
	client *alipay.Client
	err    error
)

func (AliApi) Pay(c *gin.Context, tradeNo string, totalAmount string) string {
	client, err = core.InitAlipayClient()
	if err != nil {
		logrus.Error("初始化阿里支付失败")
		return ""
	}
	var p = alipay.TradePagePay{}
	p.NotifyURL = global.Config.Aalipay.KServerDomain + "/api/alipay/notify"
	p.ReturnURL = global.Config.Aalipay.KServerDomain + "/api/alipay/callback"
	p.Subject = global.Config.Aalipay.Subject + ":" + tradeNo
	p.OutTradeNo = tradeNo
	p.TotalAmount = totalAmount
	p.ProductCode = "FAST_INSTANT_TRADE_PAY"
	//订单过期时间
	p.TimeExpire = GenerateTimeExpire(global.Config.Aalipay.OrderExpire)
	p.QRPayMode = "4" // PC扫码支付的方式，支持前置模式和跳转模式。
	p.QRCodeWidth = "300"
	//付款最晚间隔时间
	//p.TimeoutExpress = "1m"
	url, _ := client.TradePagePay(p)
	return url.String()
}

func (AliApi) Callback(c *gin.Context) {
	// 解析请求参数
	if err := c.Request.ParseForm(); err != nil {
		log.Println("解析请求参数发生错误", err)
		res.FailWithMsg(c, "error:解析请求参数发生错误")
		return
	}

	// 获取通知参数
	outTradeNo := c.Request.Form.Get("out_trade_no")

	// 验证签名
	if err := client.VerifySign(c.Request.Form); err != nil {
		log.Println("回调验证签名发生错误", err)
		res.FailWithMsg(c, "error:回调验证签名发生错误")
		return
	}

	log.Println("回调验证签名通过")

	// 查询订单状态
	var p = alipay.TradeQuery{}
	p.OutTradeNo = outTradeNo

	rsp, err := client.TradeQuery(c, p)
	if err != nil {
		log.Printf("验证订单 %s 信息发生错误: %s", outTradeNo, err.Error())
		res.FailWithMsg(c, "error"+fmt.Sprintf("验证订单 %s 信息发生错误: %s", outTradeNo, err.Error()))
		return
	}

	if rsp.IsFailure() {
		log.Printf("验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Msg, rsp.SubMsg)
		res.FailWithMsg(c, "error"+fmt.Sprintf("验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Msg, rsp.SubMsg))
		return
	}
	res.OkWithMsg(c, fmt.Sprintf("订单 %s 支付成功", outTradeNo))

}

func (a AliApi) Notify(c *gin.Context) {
	// 解析请求参数
	if err := c.Request.ParseForm(); err != nil {
		log.Println("解析请求参数发生错误", err)
		res.FailWithMsg(c, "error:解析请求参数发生错误")

		return
	}

	// 解析异步通知
	notification, err := client.DecodeNotification(c.Request.Form)
	if err != nil {
		log.Println("解析异步通知发生错误", err)
		res.FailWithMsg(c, "error:解析异步通知发生错误")

		return
	}

	log.Println("解析异步通知成功:", notification.NotifyId)

	// 查询订单状态
	var p = alipay.NewPayload("alipay.trade.query")
	p.AddBizField("out_trade_no", notification.OutTradeNo)

	var rsp *alipay.TradeQueryRsp
	if err := client.Request(c, p, &rsp); err != nil {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s", notification.OutTradeNo, err.Error())
		res.FailWithMsg(c, "error"+fmt.Sprintf("异步通知验证订单 %s 信息发生错误: %s", notification.OutTradeNo, err.Error()))
		return
	}

	if rsp.IsFailure() {
		log.Printf("异步通知验证订单 %s 信息发生错误: %s-%s", notification.OutTradeNo, rsp.Msg, rsp.SubMsg)
		res.FailWithMsg(c, "error"+fmt.Sprintf("异步通知验证订单 %s 信息发生错误: %s-%s", notification.OutTradeNo, rsp.Msg, rsp.SubMsg))
		return
	}
	//订单支付成功
	log.Printf("支付宝订单 %s 支付成功", notification.OutTradeNo)
	err = a.orderservice.OrderSuccess(notification.OutTradeNo)
	if err != nil {
		res.FailWithMsg(c, "数据库订单异常")
		return
	}
	client.ACKNotification(c.Writer)

}

// GenerateTimeExpire 返回当前时间加上指定分钟数的格式化字符串
func GenerateTimeExpire(minutes int) string {
	// 获取当前时间
	currentTime := time.Now()

	// 当前时间加指定的分钟数
	expireTime := currentTime.Add(time.Duration(minutes) * time.Minute)

	// 格式化时间为 "yyyy-MM-dd HH:mm:ss"
	formattedExpireTime := expireTime.Format("2006-01-02 15:04:05")

	return formattedExpireTime
}
